home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / news / inn1.000 / inn1.4sec-linux-src.tar / inn / samples / innwatch < prev    next >
Text File  |  1993-03-18  |  7KB  |  325 lines

  1. #! /bin/sh
  2. ##  $Revision: 1.11 $
  3. ##  Watch the state of the system relative to the news subsystem.
  4. ##  As controlled by the control file, when space or inodes are almost
  5. ##  exhausted innd is throttled, or paused, similarly if the load is
  6. ##  too high - when conditions revert to normal, innd is restarted.
  7. ##  No logging is done here, watch for syslog reports from innd.
  8. ##  Written by Mike Cooper <mcooper@usc.edu>.
  9. ##  Extensively modified by <kre@munnari.oz.au>.
  10. ##  Watch a log file and send mail when it gets new output by
  11. ##    Steve Groom <stevo@elroy.Jpl.Nasa.Gov>
  12. ##  Steve's extensions merged in innwatch by
  13. ##    <Christophe.Wolfhugel@grasp.insa-lyon.fr>
  14.  
  15. ##  =()<. @<_PATH_SHELLVARS>@>()=
  16. . /news/lib/innshellvars
  17.  
  18. PROGNAME=innwatch
  19. LOCK=${LOCKS}/LOCK.${PROGNAME}
  20. DAILY=${LOCKS}/LOCK.news.daily
  21. ##  Where to put the timestamp file (directory and filename).
  22. TIMESTAMP=${LOCKS}/${PROGNAME}.time
  23.  
  24. ##  Logfile to watch. Comment out if no logwatch.
  25. LOGFILE=${MOST_LOGS}/news.crit
  26.  
  27. ##  Parse JCL.
  28. while [ $# -gt 0 ] ; do
  29.     case X"$1" in
  30.     X-f)
  31.     FILE=$2
  32.     shift
  33.     ;;
  34.     X-f*)
  35.     FILE=`expr "$1" : '-s\(.*\)'`
  36.     ;;
  37.     X-l)
  38.     LOGFILE=$2
  39.     shift
  40.     ;;
  41.     X-l*)
  42.     LOGFILE=`expr "$1" : '-s\(.*\)'`
  43.     ;;
  44.     X-t)
  45.     SLEEPTIME=$2
  46.     shift
  47.     ;;
  48.     X-t*)
  49.     SLEEPTIME=`expr "$1" : '-t\(.*\)'`
  50.     ;;
  51.     X--)
  52.     shift
  53.     break
  54.     ;;
  55.     X-*)
  56.     echo "${PROGNAME}:  Unknown flag $1" 1>&2
  57.     exit 1
  58.     ;;
  59.     *)
  60.     break
  61.     ;;
  62.     esac
  63.     shift
  64. done
  65.  
  66. ##  Process arguments.
  67. if [ $# -ne 0 ] ; then
  68.     echo "Usage:  ${PROGNAME} [flags]" 1>&2
  69.     exit 1
  70. fi
  71.  
  72. trap '' 2
  73.  
  74. ##  Anyone else there?
  75. shlock -p $$ -f ${LOCK} || {
  76.     echo "${PROGNAME}: [$$] locked by [`cat ${LOCK}`]"
  77.     exit 0
  78. }
  79.  
  80. trap 'rm -f ${LOCK} ${WATCHPID} ; exit 1' 1 3 15
  81. echo "$$" > ${WATCHPID}
  82.  
  83. ##  The reason why we turned INND off, and its, and our current state.
  84. REASON=''
  85. INND=''
  86. STATE=''
  87.  
  88. trap '(
  89.     echo "${PROGNAME} waiting for INND to start (pid: $$)"
  90.     date
  91.     ) >${INNWSTATUS}' 2
  92.  
  93. ##  We need to remember the process ID of innd, in case one exits
  94. ##  But we need to wait for innd to start before we can do that
  95. while PID=`cat ${SERVERPID} 2>/dev/null`; test -z "${PID}"; do
  96.     sleep ${SLEEPTIME}
  97. done
  98.  
  99. trap '(
  100.     if [ -z "${STATE}" ]; then
  101.         echo "${PROGNAME} state RUN interval ${SLEEPTIME} pid $$"
  102.     else
  103.         echo "${PROGNAME} state ${STATE} interval ${SLEEPTIME} pid $$"
  104.     fi
  105.     if [ -z "${INND}" ]; then
  106.         X=GO
  107.     else
  108.         X="${INND}"
  109.     fi
  110.     test -n "${REASON}" && X="${X}: ${REASON}"
  111.     echo "INND state ${X}"
  112.     date
  113.     ) >${INNWSTATUS}' 2
  114.  
  115. cd ${SPOOL}
  116.  
  117. NEXTSLEEP=1
  118. HASEXITED=false
  119.  
  120. while { sleep ${NEXTSLEEP} & wait; } ; : ; do
  121.     NEXTSLEEP=${SLEEPTIME}
  122.  
  123.     ##  If news.daily is running, idle:  we don't want to change the
  124.     ##  status of anything while news.daily may be depending on what we
  125.     ##  have done.
  126.     test -f "${DAILY}" && continue
  127.  
  128.     ## Check to see if INND is running.
  129.     ## Notify NEWSMASTER if it has stopped or just restarted.
  130.     if ctlinnd -s -t 120 mode 2>/dev/null ; then
  131.     ${HASEXITED} && {
  132.         HASEXITED=false
  133.         ${MAILCMD} -s "INND is now running" ${NEWSMASTER} </dev/null
  134.     }
  135.     else
  136.     ${HASEXITED} || {
  137.         HASEXITED=true
  138.         ${MAILCMD} -s "INND is NOT running" ${NEWSMASTER} </dev/null
  139.     }
  140.     continue
  141.     fi
  142.  
  143.     ##  If innd has exited & restarted, put the new one into the
  144.     ##  same state the old one was in
  145.  
  146.     nPID=`cat ${SERVERPID} 2>/dev/null`
  147.     test -n "${nPID}" -a "${PID}" -ne "${nPID}" && {
  148.     test -n "${INND}" -a "${INND}" != go && ctlinnd -s "${INND}" "${REASON}"
  149.     PID="${nPID}"
  150.     }
  151.  
  152.     VALUE=0
  153.     PREVEXP=''
  154.  
  155.     exec 3<&0
  156.     exec 0<${CTLWATCH}
  157.  
  158.     LINE=0
  159.     while read line ; do
  160.     LINE=`expr ${LINE} + 1`
  161.     test -z "$line" && continue
  162.  
  163.     ##  The first character on the line is the field delimiter,
  164.     ##  except '#' which marks the line as a comment
  165.     delim=`expr "${line}" : '\(.\).*'`
  166.     test "X${delim}" = 'X#' && continue
  167.  
  168.     ##  Parse the line into seven fields, and assign them to local vars.
  169.     ##  You're welcome to work out what's going on with quoting in
  170.     ##  the next few lines if you feel inclined.
  171.     eval `trap '' 2; echo "${line}" \
  172.         | ${SED} -e "s/'/'\"'\"'/g" \
  173.             -e "s/[     ]*\\\\${delim}[     ]*/\\\\${delim}/g" \
  174.         | awk -F"${delim}" '{ print    "LAB='"'"'" $2 "'"'"'", \
  175.                         "CND='"'"'" $3 "'"'"'", \
  176.                         "EXP='"'"'" $4 "'"'"'", \
  177.                         "TST='"'"'" $5 "'"'"'", \
  178.                         "LIM='"'"'" $6 "'"'"'", \
  179.                         "CMD='"'"'" $7 "'"'"'", \
  180.                         "CMT='"'"'" $8 "'"'"'" }'`
  181.  
  182.     ##  If there's no label, the label is the line number.
  183.     test -z "${LAB}" && LAB=${LINE}
  184.  
  185.     ##  Should we act on this line?  We will if one (or more) of the
  186.     ##  specified conditions is satisfied.
  187.     for X in a b; do    # meaningless trash because we have no goto
  188.         if [ -z "${CND}" ]; then
  189.         X=-
  190.         else
  191.         X="${CND}"
  192.         fi
  193.         set -$- X ${X}; shift
  194.         for cnd
  195.         do
  196.         case "${cnd}" in
  197.         -)
  198.             test -n "${STATE}" -a "X${STATE}" != "X${LAB}" && continue
  199.             ;;
  200.         +)
  201.             test -n "${STATE}" && continue
  202.             ;;
  203.         '*')
  204.             ;;
  205.         -*)
  206.             test "X-${STATE}" = "X${cnd}" && continue
  207.             ;;
  208.         *)
  209.             test "X${STATE}" != "X${cnd}" && continue;
  210.             ;;
  211.         esac
  212.         break 2;    # OK, continue with this line
  213.         done
  214.         continue 2;        # No, skip it.
  215.     done
  216.  
  217.     ##  Evaluate the expression, if there is one, and if that works.
  218.     if [ -z "${EXP}" -o "${EXP}" = "${PREVEXP}" ] \
  219.      || { PREVEXP="${EXP}"; VALUE=`trap '' 2;eval "${EXP}"`; }; then
  220.         ##  If innd is running, and test "succeeds", stop it.
  221.         case "${CMD}" in
  222.         throttle|pause)
  223.         OK=n
  224.         ;;
  225.         *)
  226.         OK=y
  227.         ;;
  228.         esac
  229.  
  230.         if [ \( -z "${STATE}" -o "${STATE}" != "${LAB}" -o "${OK}" = y \) \
  231.             -a "${VALUE}" "-${TST}" "${LIM}" ] ; then
  232.         R="${CMT} [${PROGNAME}:${LAB}] ${VALUE} ${TST} ${LIM}"
  233.         O=
  234.         case "${CMD}" in
  235.         throttle)
  236.             case "${STATE}" in
  237.             ''|go)
  238.             REASON="${R}"
  239.             ;;
  240.             *)
  241.             ;;
  242.             esac
  243.             O="${LAB}"
  244.             ARG="${REASON}"
  245.             ;;
  246.         pause)
  247.             O="${LAB}"
  248.             REASON="${R}"
  249.             ARG="${REASON}"
  250.             ;;
  251.         shutdown)
  252.             ARG="${R}"
  253.             ;;
  254.         flush)
  255.             ARG=''
  256.             O="${STATE}"
  257.             ARG="${REASON}"
  258.             ;;
  259.         go)
  260.             ARG="${REASON}"
  261.             NEXTSLEEP=1
  262.             REASON=''
  263.             ;;
  264.         exit)
  265.             exit 0
  266.             ;;
  267.         *)
  268.             break
  269.             ;;
  270.         esac
  271.  
  272.         ctlinnd -s "${CMD}" "${ARG}" && STATE="${O}" && INND="${CMD}"
  273.         break
  274.  
  275.         ##  Otherwise, if innd is not running, and reverse test succeeds
  276.         ##  restart it.
  277.         elif [ "${STATE}" = "${LAB}" -a \
  278.             \( "${CMD}" = "throttle" -o "${CMD}" = pause \) -a \
  279.             ! "${VALUE}" "-${TST}" "${LIM}" ] ; then
  280.         ctlinnd -s go "${REASON}"
  281.         STATE=''
  282.         REASON=''
  283.         INND=''
  284.  
  285.         ##  If we have started innd, run all tests again quickly in
  286.         ##  case there is some other condition that should stop it.
  287.         NEXTSLEEP=1
  288.         break
  289.         fi
  290.     fi
  291.  
  292.     done
  293.  
  294.     exec 0<&3
  295.     exec 3<&-
  296.  
  297.     if [ -n "${LOGFILE}" -a -f "${LOGFILE}" ]; then
  298.     if [ ! -f ${TIMESTAMP} ]; then
  299.         DOIT=${LOGFILE}
  300.     else
  301.         # use ls to print most recently modified file first.
  302.         # If that's ${LOGFILE}, it's changed since the last pass.
  303.         DOIT="`ls -t ${TIMESTAMP} ${LOGFILE} | sed -e 1q | grep ${LOGFILE}`"
  304.     fi
  305.  
  306.     # If the file has been modified more recently than the timestamp,
  307.     # and the file has length greater than 0, send the warning.
  308.     if [ -n "${DOIT}" -a -s ${LOGFILE} ]; then
  309.         date >${TIMESTAMP}
  310.         (
  311.         ls -l ${LOGFILE}
  312.         echo "-----"
  313.         ctlinnd -t120 mode
  314.         echo "-----"
  315.         cat ${LOGFILE}
  316.         ) 2>&1 \
  317.         | ${MAILCMD} -s "${PROGNAME} warning: messages in ${LOGFILE}" \
  318.         ${NEWSMASTER}
  319.     fi
  320.     fi
  321.  
  322. done
  323.  
  324. rm -f ${LOCK}
  325.